PORT = 3002;

let bodyParser = require('body-parser') // 引入中间件

var express = require('express');
express.static.mime.default_type = "text/plain";

var app = express();

app.all("*", function(req, res, next) {
    //设置允许跨域的域名，*代表允许任意域名跨域
    res.header("Access-Control-Allow-Origin", "*");
    //允许的header类型
    res.header("Access-Control-Allow-Headers", "content-type");
    //跨域允许的请求方式 
    res.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS");
    if (req.method.toLowerCase() == 'options')
        res.send(200); //让options尝试请求快速结束
    else
        next();
});

app.get("/hello", function(req, res) {
    res.send({ "hello": "world" });
});

//静态资源
app.use("/monaco-editor", express.static('node_modules/monaco-editor'));
app.use("/mathjs", express.static('node_modules/mathjs/lib/browser'));
app.use(express.static('web'));

// 语法库
app.use("/git/grammar-repo", express.static('../../opendsl-grammar-repo/repo'));

// 运行时
app.use("/runtime/javascript", express.static('../../opendsl-runtime/runtime/javascript/dist'));
app.use("/parser/javascript", express.static('../../opendsl-parser/opendsl-parser-antlr/runtime/javascript/dist'));

//解析类型
app.use(bodyParser.urlencoded({ limit: "1mb", extended: true, parameterLimit: 50000 }))

var server = app.listen(PORT, function() {

    var host = server.address().address
    host = "0.0.0.0";
    var port = server.address().port

    setTimeout(() => {
        console.log("\n[START]%s 启动应用实例，访问地址为 http://%s:%s", new Date(new Date().getTime() + 8 * 60 * 60 * 1000), host, port)
    }, 500);

});

// var bodyParser = require('body-parser');
// 创建 application/json 编码解析
// var urlencodedParser = bodyParser.urlencoded({ extended: false })
var fs = require("fs");
require('path')
var process = require('child_process');

function getASTTempDirName() {

    var dir = __dirname + ("/ast-temp/" + new Date().format("yyyyMMdd-HHmmss") + "-") + (100000 + Math.round(100000 * Math.random()));
    return dir;
}

//curl http://127.0.0.1:3002/dsl/parse/ast -d '{"first":"world"}' -H "Content-Type: application/json"
app.post("/dsl/parse/to/ast", function(req, res) {
    var body = req.body;

    var dslText = decodeURI(body.dsl);
    var codeText = decodeURI(body.code);

    var dir = getASTTempDirName();

    var dslG4File = dir + "/DSL.g4";
    var codeDSLFile = dir + "/code.dsl";
    var astJSONFile = dir + "/ast.json";
    var jsCodeFile = "";

    console.info("mkdir:" + dir);
    fs.mkdirSync(dir, { recursive: true });

    fs.writeFileSync(dslG4File, dslText);
    fs.writeFileSync(codeDSLFile, codeText);

    var cmd = __dirname + "/../../opendsl-parser/opendsl-parser-antlr/runtime/javascript/gen.sh " + dslG4File + " " + codeDSLFile + " " + astJSONFile + " " + jsCodeFile;
    console.info("gen ast.json ...(" + cmd + ")");
    process.exec(cmd, function(error, stdout, stderr) {
        if (error !== null) {
            console.log('exec error: ' + error);
        }
        var astJSON = fs.readFileSync(astJSONFile);
        // var jsCode = fs.readFileSync(jsCodeFile);

        console.info("gen ast.json OK!");
        setTimeout(() => {
            [dslG4File, codeDSLFile, astJSONFile].forEach(function(file) {
                fs.rm(file, function(error) {
                    if (error) {
                        console.error("error:" + error + "(" + file + ")");
                    } else {
                        console.info("rm OK(" + file + ")");
                    }
                })
            })
        }, 3000);

        setTimeout(() => {
            fs.rmdir(dir, function(error) {
                if (error) {
                    console.error("error:" + error + "(" + dir + ")");
                } else {
                    console.info("rm OK(" + dir + ")");
                }
            });
        }, 5000);

        var data = {
            "ast": astJSON + "",
            // "js": jsCode + ""
        }
        res.send(data);

    })
});


Date.prototype.format = function(fmt) {
    var o = {
        'M+': this.getMonth() + 1,
        'd+': this.getDate(),
        'H+': this.getHours(),
        'm+': this.getMinutes(),
        's+': this.getSeconds(),
        'S+': this.getMilliseconds()
    };
    //因为date.getFullYear()出来的结果是number类型的,所以为了让结果变成字符串型，下面有两种方法：
    if (/(y+)/.test(fmt)) {
        //第一种：利用字符串连接符“+”给date.getFullYear()+''，加一个空字符串便可以将number类型转换成字符串。
        fmt = fmt.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length));
    }
    for (var k in o) {
        if (new RegExp('(' + k + ')').test(fmt)) {
            //第二种：使用String()类型进行强制数据类型转换String(date.getFullYear())，这种更容易理解。
            fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (('00' + o[k]).substr(String(o[k]).length)));
        }
    }
    return fmt;
};